/**
 * prefences class of extension.
 *
 * controls functionality of preferences pane. there are 4 settings
 * for now: "source site", "default stock", "refresh interval" and
 * "source link behaviour"
 */
var prefs = function() {
	/* bof private area */

	/**
	 * @private variable
	 * XPCOM Interface, mozilla's preferences service component pointer to
	 * read-write settings from-to user profile files.
	 */
	var prefBranch;

	/**
	 * @private variable
	 * Array, holds imkb stocks list read from stocks.properties.
	 */
	var stocks = [];

	/**
	 * @private variable
	 * Array, available source site list.
	 */
	var sources = [isnet, akbank];

	/**
	 * @private function
	 * gets mozilla's prefences service component with a singleton
	 * pattern.
	 *
	 * @return XPCOM Interface prefBranch
	 */
	var getPrefBranch = function() {
		if (!prefBranch) {
			prefBranch = Components.classes['@mozilla.org/preferences-service;1'].getService();
			prefBranch = prefBranch.QueryInterface(Components.interfaces.nsIPrefBranch);
		}
		return prefBranch;
	};

	/**
	 * @private function
	 * creates a menupopup element which is filled by options of
	 * passed setting. if setting.options is array, menuitem label
	 * will be array element. if setting.options is a hash, menuitem
	 * label will be hash element key and menuitem value will be hash
	 * element value.
	 *
	 * @param Hash setting, see prefs.settings variable comments for
	 * detailed information.
	 *
	 * @return void
	 */
	var loadMenuPopup = function(setting) {
		var target = document.getElementById(setting.target);
		var popup = document.createElement("menupopup");
		var options = (setting.options instanceof Array)
			? setting.options
			: $H(setting.options);
		options.each(function(option) {
			var item = document.createElement("menuitem");
			if (setting.options instanceof Array) {
				item.setAttribute("label", option);
			} else {
				item.setAttribute("label", option.key);
				item.setAttribute("value", option.value);
			}
			popup.appendChild(item);
		});
		target.appendChild(popup);
		target.selectedIndex = prefs.getIntPref(setting.target, setting.default_value || 0);
	};

	/**
	 * @private function
	 * saves menupopup's selected index to mozilla's preferences
	 * service component.
	 *
	 * @param Hash setting, see prefs.settings variable comments for
	 * detailed information.
	 *
	 * @return void
	 */
	var saveMenuPopup = function(setting) {
		var target = document.getElementById(setting.target);
		prefs.setIntPref(setting.target, target.selectedIndex);
	};

	/**
	 * @private function
	 * gets link target options array in current locale.
	 *
	 * @return Array, of link target options.
	 */
	var getLinkLocations = function() {
		var locale = document.getElementById("string-bundle");
		return [
				locale.getString("options.CURRENT_TAB"),
				locale.getString("options.NEW_TAB"),
				locale.getString("options.NEW_WINDOW"),
				locale.getString("options.UNFOCUSED_TAB")
				];
	};

	/**
	 * @private function
	 * gets refresh interval range. minimum is 1, and maximum is 60,
	 * and 1 unit demonstrates one minute.
	 *
	 * @return Array, of refresh interval options.
	 */
	var getRefreshIntervals = function() {
		return $R(1, 60).toArray();
	};

	/**
	 * @private function
	 * gets names of source sites.
	 *
	 * @return Array, of source site names.
	 */
	var getSourceSiteNames = function() {
		return sources.map(function(item) {
			return item.sitename;
		});
	};

	/**
	 * @private variable
	 * Hash, stores common template for a menupopup.
	 */
	var menupopup = {
		load: loadMenuPopup,
		save: saveMenuPopup,
		options: []
	};
	/* eof private area */

	return {
	/* bof public area */

		/**
		 * @private function
		 * Integer, source site link target options.
		 */
		CURRENT_TAB: 0,
		NEW_TAB: 1,
		NEW_WINDOW: 2,
		UNFOCUSED_TAB: 3,

		/**
		 * @public variable
		 * Hash, stores all the settings that is saved on preferences
		 * service. there must have a setting template for every xul
		 * element (there is just a menupopup template for now). there
		 * are 4 items in this template: "target" is the menupopup id
		 * where menuitems are placed. "options" is the list that
		 * determines menuitems. "load" is the function to create a
		 * menuitem in target menupopup. "save" is the function to
		 * save target menupopup's selected menuitem to the mozilla's
		 * preferences service component.
		 *
		 * there are 4 settings for now: "source site", "default
		 * stock", "refresh interval" and "source link behaviour"
		 */
		settings: {
			source_site: Object.extend({target: 'prefs.source_site'}, menupopup),
			load_location: Object.extend({target: 'prefs.load_location'}, menupopup),
			default_stock: Object.extend({target: 'prefs.default_stock'}, menupopup),
			refresh_interval: Object.extend({target: 'prefs.refresh_interval', default_value: 2}, menupopup)
		},

		/**
		 * @public function
		 * gets source site handler.
		 *
		 * it's possible to retrieve stock information from different
		 * sources, this handler points to the adaptor for selected source
		 * site.
		 */
		get_source_site: function() {
			var chosen_source_index = prefs.getIntPref(prefs.settings.source_site.target, 0); // 0 is ISNET
			return sources[chosen_source_index];
		},

		/**
		 * @public function
		 * gets imkb stocks list in alphabetical order. it's public
		 * because it's also needed to be called from imkbizle class.
		 *
		 * @return Array, of imkb stocks.
		 */
		getStocks: function() {
			//TODO: there should be a better way to get a sorted list.
			if (stocks.length == 0) {
				// get stock list from properties file with singleton pattern.
				var enumerator = document.getElementById("stock-bundle").strings;
				while (enumerator.hasMoreElements()) {
					var property = enumerator.getNext().QueryInterface(Components.interfaces.nsIPropertyElement);
					stocks.push(property.key);
				}
				stocks.sort();
			}
			return stocks;
		},

		/**
		 * @public function
		 * sets integer preference in mozilla's preferences service
		 * component. "imkbizle." prefix is used for saved items.
		 *
		 * @param String name, the key name for prefence to
		 * query. "imkbizle." prefix is added to "name" parameter
		 * before querying saved items
		 * @param Integer value, to be saved in prefences service.
		 *
		 * @return void.
		 */
		setIntPref: function(name, value) {
			getPrefBranch().setIntPref("imkbizle." + name, value);
		},

		/**
		 * @public function
		 * gets integer preference from mozilla's preferences service
		 * component.
		 *
		 * @param String name, the key name for prefence to
		 * query. "imkbizle." prefix is added to "name" parameter
		 * before querying saved items
		 * @param Integer defaultval, if no item is found in saved
		 * list," defaultval" will be returned.
		 *
		 * @return Integer, value saved for imkbizle."name" key. if
		 * doesn't exist in saved list, defaultval.
		 */
		getIntPref: function(name, defaultval) {
			var val;
			try {
				val = getPrefBranch().getIntPref("imkbizle." + name);
			} catch(err) {
				val = defaultval;
			}
			return val;
		},

		/**
		 * @public function
		 * saves all settings to mozilla's preferences service.
		 *
		 * @return void.
		 */
		save: function() {
			$H(prefs.settings).each(function(item) {
				item.value.save(item.value);
			});
		},

		/**
		 * @public function
		 * load's options of all settings defined. calls "load"
		 * functions of all settings' targets to fulfill xul elements
		 * in preferences dialog pane.
		 *
		 * @return void.
		 */
		load: function() {
			prefs.settings.source_site.options = getSourceSiteNames();
			prefs.settings.load_location.options = getLinkLocations();
			prefs.settings.refresh_interval.options = getRefreshIntervals();
			prefs.settings.default_stock.options = prefs.getStocks();
			$H(prefs.settings).each(function(item) {
				item.value.load(item.value);
			});
		},

	/* eof public area */
	};
}()
